package com.jinzhi.sms.support;

import com.jinzhi.api.exception.IFastApiException;
import com.jinzhi.common.type.ApiEnumError;
import com.jinzhi.common.utils.EhCacheUtil;
import com.jinzhi.common.utils.HttpContextUtils;
import com.jinzhi.jzweb.utils.RedisUtil;
import com.jinzhi.sms.config.SmsBasicConfigProperties;
import com.jinzhi.sms.utils.IpAddressUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.data.redis.core.RedisTemplate;

import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * <pre>
 *
 * </pre>
 * <small> 2018/8/31 16:45 | Aron</small>
 */
@Slf4j
public class SmsManager implements SmsVerify {

    private SmsSender smsSender;
    private SmsBasicConfigProperties properties;
    private Cache cache;

    public SmsManager(){}

    public SmsManager(SmsSender sender, SmsBasicConfigProperties properties, Cache cache){
        this.smsSender = sender;
        this.properties = properties;
        this.cache = cache;

    }

    //登录验证码
    public void send(String prefix, String mobile,String smsDemo) {
        String code = getCode();
        //发送手机短信
        smsSender.send(mobile, code, smsDemo);
        if (StringUtils.isNotBlank(code)) {
            String key = properties.getCacheKeyPrefix() + ":" +  prefix + ":" + mobile;
            // 加入缓存
            if(log.isDebugEnabled()){
                log.debug("【SMS】cache.put({}, {})", properties.getCacheKey() + ":" + key, code);
            }
            cache.put(key, code);
        }
    }
    //企业注册验证码
    public void enterpriseSend(String prefix, String mobile,String smsDemo) {
        String code = getCode();

        //发送手机短信
        smsSender.send(mobile, code, smsDemo);
        if (StringUtils.isNotBlank(code)) {
          //  String key = "enAdd" + ":" +  prefix + ":" + mobile;
            String key = properties.getCacheKeyPrefix() + ":" +  prefix + ":" + mobile;
            // 加入缓存
            if(log.isDebugEnabled()){
                log.debug("【SMS】cache.put({}, {})", properties.getCacheKey() + ":" + key, code);
            }
            cache.put(key, code);
        }
    }
    //注册验证码
    public void sendreg(String prefix, String mobile,String smsDemo) {
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        String code = getCode();


        String outIP = "";
        if (request != null) {
            //获取公网ip
            outIP = getRealClientIP(request);
        }

        // 获取缓存中的key
        String cacheKeyForMobile = "sms:count:mobile:" + mobile;
//        String cacheKeyForIp = "sms:count:ip:" + outIP;

        // 分别获取手机号和IP的发送次数
        Integer mobileCount = 0;
        Integer ipCount = 0;
        Cache.ValueWrapper mobileWrapper = cache.get(cacheKeyForMobile);
//        Cache.ValueWrapper ipWrapper = cache.get(cacheKeyForIp);

        if (mobileWrapper != null) {
            mobileCount = (Integer) mobileWrapper.get();
        }
//        if (ipWrapper != null) {
//            ipCount = (Integer) ipWrapper.get();
//        }

        // 判断手机号是否已经达到每天20次的限制
        if (mobileCount >= 20) {
            log.warn("手机号 {} 今日发送短信次数已达上限", mobile);
            throw new RuntimeException("手机号发送短信次数已达今日上限，请明日再试");
        }

//        // 判断IP是否已经达到每天20次的限制
//        if (ipCount >= 20) {
//            log.warn("IP {} 今日发送短信次数已达上限", outIP);
//            throw new RuntimeException("IP发送短信次数已达今日上限，请明日再试");
//        }

        // 发送短信
        smsSender.send(mobile, code, smsDemo);

        // 如果发送成功，更新缓存中的计数
        mobileCount += 1;
        ipCount += 1;
        cache.put(cacheKeyForMobile, mobileCount);
//        cache.put(cacheKeyForIp, ipCount);
        System.out.printf("接收短信手机号:%s%n",mobile);
        System.out.println("当前手机号发送短信的次数为: " + mobileCount);
        System.out.println("当前IP发送短信的次数为: " + ipCount);

        // 使用 RedisTemplate 来设置过期时间，当天晚上12点缓存后过期
        if (mobileCount == 1) {
            // 计算过期时间（到今天午夜的秒数）
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime midnight = LocalDateTime.of(now.toLocalDate(), LocalTime.MIDNIGHT).plusDays(1);
            long expireTime = Duration.between(now, midnight).getSeconds();
            // 设置过期时间
            RedisUtil.expire(cacheKeyForMobile, expireTime);
//            RedisUtil.expire(cacheKeyForIp, expireTime);
        }
        if (StringUtils.isNotBlank(code)) {
            String key = properties.getCacheKeyPrefix() + ":" +  prefix + ":" + mobile;
            // 加入缓存
            if(log.isDebugEnabled()){
                log.debug("【SMS】cache.put({}, {})", properties.getCacheKey() + ":" + key, code);
            }
            cache.put(key, code);
            EhCacheUtil.put(mobile+"wx", code);
        }

    }
    // 获取客户端真实IP地址的辅助方法
    private String getRealClientIP(HttpServletRequest request) {
        String ip = request.getHeader("Ip");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = "127.0.0.1";
        }
        return ip;
    }

    //修改密码验证码
    public void sendPassword(String prefix, String mobile,String smsDemo) {
        String code = getCode();

        //发送手机短信
        smsSender.send(mobile, code, smsDemo);
        if (StringUtils.isNotBlank(code)) {
            String key = properties.getCacheKeyPrefix() + ":" +  prefix + ":" + mobile;
            // 加入缓存
            if(log.isDebugEnabled()){
                log.debug("【SMS】cache.put({}, {})", properties.getCacheKey() + ":" + key, code);
            }
            cache.put(key, code);
        }
    }

    public void send(String mobile, String templateCode,Map templateParam){
        //发送手机短信
        smsSender.send(mobile, templateCode, templateParam);



    }

    public void send1(String mobile, String templateCode,String signName,Map messageContent) {
        smsSender.send(mobile,templateCode,signName,messageContent);

//        if (StringUtils.isNotBlank(code)) {
//            String key = properties.getCacheKeyPrefix() + ":" + mobile;
//
//            // 加入缓存
//            if(log.isDebugEnabled()){
//                log.debug("【SMS】cache.put({}, {})", properties.getCacheKey() + ":" + key, code);
//            }
//            cache.put(key, code);
//        }
    }

    @Override
    public void verify(String prefix, String mobile, String code) {
        String key = properties.getCacheKeyPrefix() + ":" +  prefix + ":" + mobile;
//        if (!mobile.equals("18711358618")){
            Cache.ValueWrapper valueWrapper = cache.get(key);
            if (valueWrapper == null || !valueWrapper.get().equals(code)) {
                throw new IFastApiException(ApiEnumError.apiSmsCodeInvalid.getCodeStr());
            }
            // 移除缓存
            if(log.isDebugEnabled()){
                log.debug("【SMS】cache.evict({}, {})", properties.getCacheKey() + ":" + key, code);
            }
//        }
        cache.evict(key);
    }

    @Override
    public boolean verify1(String prefix, String mobile, String code) {
        String key = properties.getCacheKeyPrefix() + ":" +  prefix + ":" + mobile;
//        if (!mobile.equals("18711358618")){
        Cache.ValueWrapper valueWrapper = cache.get(key);
        if (valueWrapper == null || !valueWrapper.get().equals(code)) {
           return false;
        }
        // 移除缓存
        if(log.isDebugEnabled()){
            log.debug("【SMS】cache.evict({}, {})", properties.getCacheKey() + ":" + key, code);
        }
//        }
        cache.evict(key);
        return true;
    }


    @Override
    public boolean loginVerify(String prefix, String phone, String code) {
        String key = properties.getCacheKeyPrefix() + ":" +  prefix + ":" + phone;
        Cache.ValueWrapper valueWrapper = cache.get(key);
        if (valueWrapper == null || !valueWrapper.get().equals(code)) {
            return false;
        }

        // 移除缓存
        if(log.isDebugEnabled()){
            log.debug("【SMS】cache.evict({}, {})", properties.getCacheKey() + ":" + key, code);
        }
        cache.evict(key);
        return true;
    }

    /**
     * <pre>
     * 生成随机码
     * </pre>
     */
    public String getCode(){
        return new Random().nextInt(8999) + 1000 + "";
    }

}
